package com.hyxt.utils;

import com.hyxt.DTO.CommonMessage;
import com.hyxt.DTO.T809_MessageHeader;
import com.hyxt.superviseservice.CommonMessageBody;
import com.hyxt.superviseservice.IMessage;
import com.hyxt.superviseservice.IMessageBody;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @Project: CNPC_VMS
 * @Title: T808_ProtocolAnalysis
 * @Description: 部标809协议解析类
 * @author: guanhl
 * @date: 2014年4月4日 上午12:00:14
 * @company: Beijing Huayou Information andCommunication Technology Co.,Ltd
 * @Copyright: Copyright (c) 2014
 * @version V2.0
 */
public class T809_ProtocolAnalysis {

	private static Log log = LogFactory.getLog(T809_ProtocolAnalysis.class);

	int[] codes;

	public T809_ProtocolAnalysis() {
		this.codes = new int[] { 10000000, 20000000, 30000000 };
	}

	public T809_ProtocolAnalysis(int[] codes2) {
		this.codes = codes2;
	}

	/**
	 * @Description:对数据体进行拆包解析
	 */
	public IMessage<?> unpack(byte[] data) throws ProtocolCheckExeption, ProtocolEscapeExeption {

		// 转义
		byte[] reverseBytes = null;

		reverseBytes = T809_Util.reverseEscapeData(data);
		// 校验

		reverseBytes = data;
		// 用校验方法算出的crc校验码
		short checkCode = BytesUtil.parseBytesToShort(T809_Util.check(reverseBytes));
		// 数据体携带的crc校验码
		short crcCode = BytesUtil.parseBytesToShort(BytesUtil.cutBytes(data.length - 3, 2, data));
		// 判断crc校验码是否正确
		boolean check = checkCode == crcCode;
		CommonMessage<?> message = null;
		log.debug("message data check result: " + check);
		log.debug(BytesUtil.bytesToHexString(data) + "!");
		log.debug(BytesUtil.bytesToHexString(reverseBytes) + "?");
		// 如果crc校验码验证通过，开始解析数据
		if (true) {
			// 解析消息头
			T809_MessageHeader header = (T809_MessageHeader) T809_Util.getHeader(reverseBytes);
			// 根据消息ID选择处理器
			T809_Process<?> process = T809_MessageProcessManager.getProcess((Integer) T809_Util.getMessageID(reverseBytes, codes));

			log.debug("handle by process " + process.getClass().getName());

			CommonMessageBody body = null;

			byte[] bodyData = BytesUtil.cutBytes(23, reverseBytes.length - 26, reverseBytes);

			// 解密已改到getmessageID中，如果数据体加密标识为1，进行解密
			if (header.getEncryptFlag() == 0x01) {
				bodyData = T809_Util.encrypt(header.getEncryptKey(), bodyData, codes[0], codes[1], codes[2]);
			}
			// 解析消息体
			body = process.getBody(header, bodyData);
			// 合成消息
			message = new CommonMessage<CommonMessageBody>((Integer) header.getMessageID(), header, body);
		} else {
			throw new ProtocolCheckExeption(ByteUtil.bytes2BCDStr(data));
		}
		return message;
	}

	@SuppressWarnings("unchecked")
	/**
	 * @Description:返回消息体的打包类，每个消息打包类中会重写这个方法
	 */
	public <B extends IMessageBody> byte[] pack(IMessage<B> message) {
		T809_Process<B> process = null;
		try{
		  process = (T809_Process<B>) T809_MessageProcessManager.getProcess((Integer) message.getMessageBody().getMessageID());
		} catch(Exception e){
			e.initCause(new Throwable("message id :" + (message==null?"null":message.getMessageID())));
			e.printStackTrace();
		}
		return process.packData((CommonMessage<B>) message);
	}

	public static void main(String[] args) {

		// byte[] aaa=
		// BytesUtil.toStringHex("C9FF5E24242A241C1C1C1C1C1C1C1C1C1C1C1C1C1E0E1E1C1C1C381C111B1BC31606391B5E2F1DD467921C1C1C1C1C1C1C1C1C581C1C1C1C1C1D1C1C1C1C");
		byte[] aaa = BytesUtil
				.toStringHex("C9FF5E5A2E2E1C1C1C1C1C1C1C1C1C1C1C1C1C1E0E1E1C1C1C381C161B1BC31237071B22EBBE1DD41D431C1C1C1C1C1C1C1C1D2A1C1C1C1C1C1D1C1C1C1C41D75D");
		// d5e342383836380000000000000000000000000002120200000024000d0707df0a1a2507423301c87b8e0000000000000000004400000000000100000000
		// //d5e3424632320000000000000000000000000002120200000024000a0707df0e2b1b073ef7a201c8015f00000000000000000136000000000001000000005dcb41
		// byte[] aaa=
		// BytesUtil.toStringHex("d5e34238413336330000000000000000000000000002120200000024000a0707df0f0f3807426d7a01c92f24000b000b0000000000e7000000000001000000001");
		byte[] bbb = T809_Util.encrypt(0x002A3D1C, aaa, 10000000, 10000000, 30000000);
		log.debug(BytesUtil.bytesToHexString(bbb));
		// byte[] aaa =
		// BytesUtil.toStringHex("d5e34246323200000000000000000000000000");
		// try {
		// log.debug(new String(aaa,"GBK"));
		// } catch (UnsupportedEncodingException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
	}
}
